package com.itbour.service.yjx.user.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.OnExceptionContext;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.SendCallback;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.itbour.com.page.JspPage;
import com.itbour.com.page.Page;
import com.itbour.common.util.StringUtils;
import com.itbour.dao.yjx.user.SendRocketDao;
import com.itbour.dto.yjx.user.IdTmpTypeTimeDto;
import com.itbour.dto.yjx.user.ItbQaInfoDto;
import com.itbour.dto.yjx.user.RocketState;
import com.itbour.dto.yjx.user.RocketTAG;
import com.itbour.dto.yjx.user.TmpChkIdDto;
import com.itbour.dto.yjx.user.YjscItemTotal;
import com.itbour.service.yjx.user.SendRocketMesService;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Client;
import com.qiniu.util.CompareMap;
import com.qiniu.util.HttpRequest;
import com.qiniu.util.StringMap;


/**
 * @author 李琦
 */
public class SendRocketServiceImpl implements SendRocketMesService {

	private Producer producer;// 直接注入 生产者的注入
	private SendRocketDao sendRocketDao; // 验证判断
	private JedisPool jedisPool;// jedis连接池
	private static final String ITEM_TOTAL = "item_total";
	private static final String Yjsc_item_total = "itbour_item_total";// 一键生成 item_total
	private static final Logger logger = Logger.getLogger("sys.debug");
	
	// 单向 发送
	// 定义parm内容 {"mesg":"消息内容","tag":"标签"}
	public boolean sendRocketMes(Map<String, Object> parm) {
		JSONObject json = JSONObject.fromObject(parm); // 将消息转换成 json消息传出去
		String mesg = json.get("mesg").toString();// 将消息转成字符串
		String tag = json.get("tag").toString();
		Message msg = new Message( 
				// Message 所属的 Topic
				RocketTAG.TOPIC,
				// Message Tag 可理解为 Gmail 中的标签，对消息进行再归类，方便 Consumer 指定过滤条件在 MQ
				// 服务器过滤
				tag,
				// Message Body 可以是任何二进制形式的数据， MQ 不做任何干预
				// 需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式
				mesg.getBytes());
		// 设置代表消息的业务关键属性，请尽可能全局唯一
		// 以方便您在无法正常收到消息情况下，可通过 MQ 控制台查询消息并补发
		// 注意：不设置也不会影响消息正常收发
		msg.setKey("ORDERID_100");
		// 发送消息，只要不抛异常就是成功
		try {
			SendResult sendResult = producer.send(msg);
			assert sendResult != null;
			System.out.println("send success: " + sendResult.getMessageId());
			return true;
		} catch (ONSClientException e) {
			System.out.println("发送失败");
			return false;
		}
	}

	public Producer getProducer() {
		return producer;
	}

	public void setProducer(Producer producer) {
		this.producer = producer;
	}

	public boolean asySendRocketMes(Map<String, Object> parm) {
		try {
	        Message msg = new Message(
	                // Message 所属的 Topic
	                "TopicTestMQ",
	                // Message Tag,可理解为 Gmail 中的标签，对消息进行再归类，方便 Consumer 指定过滤条件在 MQ 服务器过滤
	                "TagA",
	                // Message Body，任何二进制形式的数据，MQ 不做任何干预，需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式
	                "Hello MQ".getBytes());
	
	        // 设置代表消息的业务关键属性，请尽可能全局唯一。以方便您在无法正常收到消息情况下，可通过 MQ 控制台查询消息并补发。
	        // 注意：不设置也不会影响消息正常收发
	        msg.setKey("ORDERID_100");
	
	        // 异步发送消息, 发送结果通过 callback 返回给客户端。
	        producer.sendAsync(msg, new SendCallback() {
	            public void onSuccess(final SendResult sendResult) {
	                // 消费发送成功
	                System.out.println("send message success. topic=" + sendResult.getTopic() + ", msgId=" + sendResult.getMessageId());
	            }
	
	            public void onException(OnExceptionContext context) {
	                // 消息发送失败，需要进行重试处理，可重新发送这条消息或持久化这条数据进行补偿处理
	                System.out.println("send message failed. topic=" + context.getTopic() + ", msgId=" + context.getMessageId());
	            }
	        });
   	
	        // 在 callback 返回之前即可取得 msgId。
	        System.out.println("send message async. topic=" + msg.getTopic() + ", msgId=" + msg.getMsgID());
	
	        // 在应用退出前，销毁 Producer 对象。注意：如果不销毁也没有问题
	        producer.shutdown();
	        return true;
		} catch (Exception e) {
			return false;
		}
	}

	// 检查
	// 定义parm内容 {"mesg":"消息内容","tag":"标签"}
	public boolean checkSendMesToJoinRedis(TmpChkIdDto chkId,Integer state,String tag) {
		String tmpstId = chkId.getSetId();
		if (chkId.getSetId()!=null) { // 通过模板组查询
			List<Long> ids = StringUtils.stringToList2(tmpstId);
			Map<String, Object> parm = new HashMap<String, Object>();
			List<String> list = new ArrayList<String>();
			for (int i = 0; i < ids.size(); i++) {
				String setId = ids.get(i).toString();
				parm.put("setId", setId);
				int num = sendRocketDao.chkIsHaveShowType(parm);
				if (num>0){
					list.add(setId);
				}
			}
			if (list.size()>0){
				Map<String, Object> mesMap = new HashMap<String, Object>();
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("setId", StringUtils.listToString(list));
				jsonObject.put("state", state); // 1是更新
				mesMap.put("tag", tag);
				mesMap.put("mesg",jsonObject);
				this.sendRocketMes(mesMap);
			}
			
		} else { // 通过统一模板ID 查询
			String tmpUTmplId = chkId.getuTmplId();
			List<Long> ids = StringUtils.stringToList2(tmpUTmplId);
			Map<String, Object> parm = new HashMap<String, Object>();

			List<String> list = new ArrayList<String>();
			for (int i = 0; i < ids.size(); i++) {
				String uTmplId = ids.get(i).toString();
				parm.put("uTmplId", uTmplId);
				int num = sendRocketDao.chkJoinRedisState(parm);
				if (num>0){
					list.add(uTmplId);
				}
			}
			if (list.size()>0){
				Map<String, Object> mesMap = new HashMap<String, Object>();
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("id", StringUtils.listToString(list));
				jsonObject.put("state", state);
				mesMap.put("tag", tag);
				mesMap.put("mesg",jsonObject);
				this.sendRocketMes(mesMap);
			}
		}
		return false;
	}

	public SendRocketDao getSendRocketDao() {
		return sendRocketDao;
	}
	public void setSendRocketDao(SendRocketDao sendRocketDao) {
		this.sendRocketDao = sendRocketDao;
	}

	public JedisPool getJedisPool() {
		return jedisPool;
	}

	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}
	
	public void sendMesUpdateRedis(String ids,Integer state,String tag){
		Map<String, Object> parm = new HashMap<String, Object>();
		JSONObject json = new JSONObject();
		json.put("id", ids);
		json.put("state", state);
		parm.put("mesg", json.toString());
		parm.put("tag", tag);
		this.sendRocketMes(parm);
	}

	
	/**
	 *  一键秀REDIS 
	 *  发消息 更新缓存
	 *  类型1：更新视频模板
	 *  类型2：删除视频模板
	 */
	public String sendMesBuildCache(Map<String, Object> parm) {
		Jedis jedis = null;
		logger.info("sendMesBuildCache 发送消息建缓存"+SendRocketServiceImpl.class.getName());
		try {
			 //获取Jedis对象
	        jedis = jedisPool.getResource();
	        if (RocketTAG.REDIS_ONLINEDB_RECORD!=null){
		        jedis.select(RocketTAG.REDIS_ONLINEDB_RECORD); // 21号  资源redis数据库
		        Map<String, String> hgetAll = jedis.hgetAll(ITEM_TOTAL);
				System.out.println(hgetAll);
				List<IdTmpTypeTimeDto> list = sendRocketDao.getAllPublishTmpl(parm);
				Map<String, String> localMap = new HashMap<String, String>();
				for (IdTmpTypeTimeDto idTmpTypeTimeDto : list) {
					String id = idTmpTypeTimeDto.getUni_item_id().toString();
					String setId = idTmpTypeTimeDto.getSet_id().toString();
					String showTypeId = idTmpTypeTimeDto.getSt_id().toString();
					String upTime = idTmpTypeTimeDto.getUpdate_time();
					String useCounts = idTmpTypeTimeDto.getShow_apply_cnt().toString();
					String key = upTime+"_"+id+"_"+useCounts+"_"+setId+"_"+showTypeId;
					localMap.put(key, id);
//					String tmp = idTmpTypeTimeDto.getUpdate_time()+"_"+idTmpTypeTimeDto.getUni_item_id()+"_"+idTmpTypeTimeDto.getShow_apply_cnt()+"_"+idTmpTypeTimeDto.getSet_id()+"_"+idTmpTypeTimeDto.getSt_id();
//					localMap.put(tmp,idTmpTypeTimeDto.getUni_item_id().toString());
				}
				System.out.println(localMap);
				List<String> idSt1 = new ArrayList<String>();
				Set<String> setId1 = new HashSet<String>();
				List<String> idSt2 = new ArrayList<String>();
				Set<String> setId2 = new HashSet<String>();
				// m1中有 m2中没有  返回 m1中的id 发送删除消息
				setId1 = CompareMap.compare(hgetAll, localMap);// 1,2,3
				setId2 = CompareMap.compare(localMap, hgetAll);// 
				
				setId1.removeAll(setId2);//
				idSt1.addAll(setId1);
				if (idSt1.size()>0) {
					String id = StringUtils.listToString(idSt1); // 需要删除的ID
					this.sendMesUpdateRedis(id, RocketState.DEL, RocketTAG.UPDATE_CACHE_SYNC);//1.发消息 删除线下设计
				}
				// m1中有 m2中没有  返回 m1中的id 发送修改消息
				idSt2.addAll(setId2);
				if (idSt2.size()>0){
					String id2 = StringUtils.listToString(idSt2); // 新增的ID
					this.sendMesUpdateRedis(id2, RocketState.UPDATE, RocketTAG.UPDATE_CACHE_SYNC);
				}
				
				System.out.println("删除的消息"+idSt1);
				System.out.println("修改的消息"+idSt2);
				logger.info("Redis===>item_total长度"+hgetAll.size());
				logger.info("Mysql===>item_total长度"+localMap.size());
				logger.info("删除消息的ID集合:"+idSt1);
				logger.info("修改消息的ID集合:"+idSt2);
				if (idSt1.size()<=0 && idSt2.size()<=0){
					return "已更新完毕";
				} else {
					return "正在更新中";
				}
	        } else {
	        	return "选库失败";
	        }
		} catch (Exception e) {
			return "更新失败"+e.getMessage();
		} finally {
			if (jedis != null){//注意这里不是关闭连接，在JedisPool模式下，Jedis会被归还给资源池。
				jedis.close();
			}
		}
	}

	public Object upItbQaInfo(Map<String, Object> parm) {
		List<ItbQaInfoDto> list = sendRocketDao.selectItbQaInfo(parm);
		System.out.println(list);
		return null;
	}

	public Page getQaInfo(Map<String, Object> parm, Integer pageNo,
			Integer pageSize) {
		Page page = null;
		int skipNum = JspPage.getStartOfPage(pageNo, pageSize);// 获取起始位置
		int totalSize = sendRocketDao.selectItbQaInfoCnt(parm);
		while (totalSize > 0 && totalSize <= skipNum) {
			skipNum = skipNum - pageSize;
			pageNo = pageNo - 1;
		}
		parm.put("pageSize", pageSize);
		parm.put("skipResults", skipNum);
		List<ItbQaInfoDto> data = sendRocketDao.selectItbQaInfo(parm);
		page = new JspPage(skipNum, totalSize, pageSize, data);
		return page;
	}

	public List<ItbQaInfoDto> getQaTmplInfo(Map<String, Object> parm) {
		return sendRocketDao.getQaTmplInfo(parm);
	}

	
	/**
	 *  一键生成 发送消息更新缓存
	 *  类型1：更新模板
	 *  类型2：删除模板
	 */
	public String sendMesUpdateYjscTmpl(Map<String, Object> parm) {
		Jedis jedis = null;
		logger.info("sendMesBuildCache 一键生成"+SendRocketServiceImpl.class.getName());
		try {
			 //获取Jedis对象
	        jedis = jedisPool.getResource();
	        if (RocketTAG.YJSC_REDIS_ONLINEDB_RECORD!=null){
		        jedis.select(RocketTAG.YJSC_REDIS_ONLINEDB_RECORD); //  27号库
		        Map<String, String> hgetAll = jedis.hgetAll(Yjsc_item_total);
				List<YjscItemTotal> list = sendRocketDao.getYJSCAllPublishTmpl(parm);
				Map<String, String> localMap = new HashMap<String, String>();
				for (YjscItemTotal yjscItemTotal : list) {
					String time = yjscItemTotal.getUpdate_time();
					String cnt = yjscItemTotal.getCnt();
					String designId = yjscItemTotal.getDesign_id();
					String key = time +"_"+cnt+"_"+designId;
					localMap.put(key, designId);
				}
				
				System.out.println(localMap);
				List<String> idSt1 = new ArrayList<String>();
				Set<String> setId1 = new HashSet<String>();
				List<String> idSt2 = new ArrayList<String>();
				Set<String> setId2 = new HashSet<String>();
				// m1中有 m2中没有  返回 m1中的id 发送删除消息
				setId1 = CompareMap.compare(hgetAll, localMap);// 1,2,3
				setId2 = CompareMap.compare(localMap, hgetAll);// 
				
				setId1.removeAll(setId2);//
				idSt1.addAll(setId1);
				if (idSt1.size()>0) {
					String id = StringUtils.listToString(idSt1); // 需要删除的ID
					this.sendMesUpdateRedis(id, RocketState.DEL, RocketTAG.yjscupdateCacheSync);
					
					String comIds = "["+id+"]";
					this.DoPost(RocketState.DEL, comIds);
				}
				
				// m1中有 m2中没有  返回 m1中的id 发送修改消息
				idSt2.addAll(setId2);
				if (idSt2.size()>0) {
					String id2 = StringUtils.listToString(idSt2); // 新增的ID
					this.sendMesUpdateRedis(id2, RocketState.UPDATE, RocketTAG.yjscupdateCacheSync);
					
					String comIds = "["+id2+"]";
					this.DoPost(RocketState.UPDATE, comIds);
				}
				
				System.out.println("删除的消息"+idSt1);
				System.out.println("修改的消息"+idSt2);
				logger.info("Redis===>item_total长度"+hgetAll.size());
				logger.info("Mysql===>item_total长度"+localMap.size());
				logger.info("删除消息的ID集合:"+idSt1);
				logger.info("修改消息的ID集合:"+idSt2);
				
				if (idSt1.size()==0 && idSt2.size() == 0){
					return "已更新完毕,请转站APP查看";
				}
				
				return "正在更新中..请稍后";
	        } else {
	        	return "获取库失败 请稍后重试";
	        }
		} catch (Exception e) {return "发送消息失败:"+e.getMessage();
		} finally {if (jedis != null)jedis.close();}
		
	}
	
	
	/**
	 * 发送 post请求 更新推荐缓存
	 * @param flg 标记1：更新 /2：删除
	 * @param ids 
	 */
	public void DoPost(int flg,String ids){
		StringBuilder param = new StringBuilder();
		String url = RocketTAG.RESTFUL_URL+"/yjsc/v2/recommend/syncRecommendCache";// 更新单个或者 多个推荐系统缓存
		param.append("flag=").append(flg).append("&ids=").append(ids);
		System.out.println(param.toString());
		String st = HttpRequest.sendPost(url, param.toString());//请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
		System.out.println(st);
	}
	
	
}
